package capricornus.io
{
	import capricornus.core.RefreshManager;
	import capricornus.core.StageManager;
	import capricornus.events.RefreshEvent;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	import flash.utils.Dictionary;
	
	/**
	 * 只有注册过的按键才能收到消息, eg:  registerKey( 49 );
	 */	
	[Event(name="keyDown", type="flash.events.KeyboardEvent")]
	[Event(name="keyUp", type="flash.events.KeyboardEvent")]
	public class KeyboardManager extends EventDispatcher
	{
		public static var instance:KeyboardManager;
		
		private var _dictKeyState:Dictionary;
		private var _dictKey:Dictionary;
		private var _dictKeyOnPress:Dictionary;
		
		private var _isAltDown:Boolean = false;
		private var _isCtrlDown:Boolean = false;
		private var _isShiftDown:Boolean = false;
		
		public function KeyboardManager()
		{
			super(null);
			init();
		}
		
		private function init():void
		{
			instance = this;
			
			_dictKeyState = new Dictionary();
			_dictKey = new Dictionary();
			_dictKeyOnPress = new Dictionary();
			
			StageManager.stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeyDown, false, 0, true );
			StageManager.stage.addEventListener( KeyboardEvent.KEY_UP, onKeyUp, false, 0, true );
			StageManager.stage.addEventListener( Event.DEACTIVATE, onDeactivate, false, 0, true );
			RefreshManager.instance.addEventListener( RefreshEvent.REFRESH, onRefresh, false, 0, true );
			
			stop();
		}
		
		/**
		 *  
		 * @param keyCode
		 * @param getEventOnPress 是否在一直按住键盘的时候也接收消息
		 * 
		 */		
		public function registerKey( keyCode:uint, getEventOnPress:Boolean=true ):void
		{
			_dictKey[keyCode] = false;
			_dictKeyOnPress[keyCode] = getEventOnPress;
		}
		
		public function clearKey( keyCode:uint ):void
		{
			if( _dictKey[keyCode] != null )
			{
				delete _dictKey[keyCode];
			}
			if( _dictKeyOnPress[keyCode] != null )
			{
				delete _dictKeyOnPress[keyCode];
			}
		}
		
		public function clearAllKey():void
		{
			var i:*;
			for( i in _dictKey )
			{
				delete _dictKey[i];
			}
			for( i in _dictKeyOnPress )
			{
				delete _dictKeyOnPress[i];
			}
		}
		
		private var _isStop:Boolean = false;
		public function stop():void
		{
			if( !_isStop )
			{
				_isStop = true;
				StageManager.stage.removeEventListener( KeyboardEvent.KEY_DOWN, onKeyDown );
				StageManager.stage.removeEventListener( KeyboardEvent.KEY_UP, onKeyUp );
				RefreshManager.instance.removeEventListener( RefreshEvent.REFRESH, onRefresh );
			}
		}
		
		public function start():void
		{
			if( _isStop )
			{
				_isStop = false;
				StageManager.stage.focus = null;
				StageManager.stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeyDown, false, 0, true );
				StageManager.stage.addEventListener( KeyboardEvent.KEY_UP, onKeyUp, false, 0, true );
				RefreshManager.instance.addEventListener( RefreshEvent.REFRESH, onRefresh, false, 0, true );
			}
		}
		
		public function getKeyState( keyCode:uint ):Boolean
		{
			return _dictKeyState[keyCode]==true;
		}
		
		private function onDeactivate( e:Event ):void
		{
			_isAltDown = false;
			_isCtrlDown = false;
			_isShiftDown = false;
			
			for( var i:* in _dictKey )
			{
				_dictKey[i] = false;
			}
			for( i in _dictKeyState )
			{
				_dictKeyState[i] = false;
			}
		}
		
		private function onKeyDown( e:KeyboardEvent ):void
		{
			_isAltDown = e.altKey;
			_isCtrlDown = e.ctrlKey;
			_isShiftDown = e.shiftKey;
			
			var keyCode:uint = e.keyCode;
			if( _dictKeyState[keyCode] != true )
			{
				if( _dictKey[keyCode] != null )
				{
					_dictKey[keyCode] = true;
					dispatchEvent( e );
				}
			}
			_dictKeyState[keyCode] = true;
		}
		
		private function onKeyUp( e:KeyboardEvent ):void
		{
			_isAltDown = e.altKey;
			_isCtrlDown = e.ctrlKey;
			_isShiftDown = e.shiftKey;
			
			var keyCode:uint = e.keyCode;
			if( _dictKeyState[keyCode]==true )
			{
				if( _dictKey[keyCode] != null )
				{
					_dictKey[keyCode] = false;
					dispatchEvent( e );
				}
			}
			_dictKeyState[keyCode] = false;
		}
		
		private function onRefresh( e:RefreshEvent ):void
		{
			for( var i:* in _dictKey )
			{
				if( _dictKey[i] && _dictKeyOnPress[i] )
				{
					dispatchEvent( new KeyboardEvent( KeyboardEvent.KEY_DOWN, false, false, 0, uint(i), 0, _isCtrlDown, _isAltDown, _isShiftDown ) );
				}
			}
		}
	}
}



